package com.edu.hre.struts.action.recruit;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.upload.FormFile;

import com.edu.hre.common.email.EMailSender;
import com.edu.hre.common.utils.BeanFinder;
import com.edu.hre.common.utils.ComboBoxInit;
import com.edu.hre.common.utils.CommonUtils;
import com.edu.hre.common.utils.StringConstants;
import com.edu.hre.db.pojo.HreJobCandidate;
import com.edu.hre.db.pojo.HreJobInterview;
import com.edu.hre.db.pojo.HreJobInterviewAttachment;
import com.edu.hre.db.pojo.HreJobVacancy;
import com.edu.hre.db.service.BaseService;
import com.edu.hre.db.utils.Compare;
import com.edu.hre.struts.form.recruit.InterviewUpdateForm;

public class InterviewUpdateAction extends DispatchAction{
	
	private static final Logger logger = Logger.getLogger(InterviewUpdateAction.class);
	private static final BaseService baseService = BeanFinder.getBean(BaseService.BEAN_NAME, BaseService.class);
	private static final EMailSender emailSender = BeanFinder.getBean(EMailSender.BEAN_NAME, EMailSender.class);
	private final String ACTION_NAME = "interviewUpdate";
	
	private String canName = "";
	private String vacName = "";
	private String canEmail = "";
	private String[] interviewerEmailList = null;
	
	public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		CommonUtils.println(CommonUtils.getSourceCodeLocation());
		InterviewUpdateForm beanForm = (InterviewUpdateForm) form;
		beanForm.setIsAddNew(true);

		if(request.getParameter(StringConstants.BTN_ADD) == null){
			
			int canId = CommonUtils.getIntParameter("canId", request);
			int vacId = CommonUtils.getIntParameter("vacId", request);
			
			if (canId > 0) {
				beanForm.setCanId(canId);
			}
			if (vacId > 0) {
				beanForm.setVacId(vacId);
			}

			beanForm.setMessage(StringConstants.BLANK);
			initFormBean(beanForm);
			return mapping.findForward(ACTION_NAME);
		}

		String message = validateForm(beanForm);
		if(!StringUtils.isBlank(message)){
			beanForm.setMessage(message);
			initFormBean(beanForm);
			return mapping.findForward(ACTION_NAME);
		}

		HreJobInterview tmp = new HreJobInterview();
		
		tmp.setCandidateId(beanForm.getCanId());
		tmp.setVacancyId(beanForm.getVacId());
		tmp.setInterviewName(getInterviewName(tmp));
		tmp.setInterviewPlace(CommonUtils.normalizeString(beanForm.getPlace()));
		tmp.setStatus(beanForm.getStatus());
		tmp.setResult(beanForm.getResult());
		
		getAllInterviewers(beanForm, tmp);

		Date date = CommonUtils.stringToDate(CommonUtils.normalizeString(beanForm.getDate()));
		if (date != null) {
			try {
				int hour = Integer.parseInt(beanForm.getHour());
				int min = Integer.parseInt(beanForm.getMin());
				date.setHours(hour);
				date.setMinutes(min);
			} catch (Exception e) {

			}
		}
		tmp.setInterviewTime(date);
		tmp.setDateCreated(new Date());
		tmp.setDateModified(new Date());
		
		boolean status = baseService.saveOrUpdate(tmp);
		if (!status) {
			beanForm.setMessage(StringConstants.INSERT_FAILURE_MESSAGE);
			initFormBean(beanForm);
			return mapping.findForward(ACTION_NAME);
		}
		
		getRecipientInfo(tmp);
		// Invite interviewers & interviewee to the interview.
		informIntervieweeToInterview(tmp);
		informInterviewerForInterview(tmp);

		FormFile attachFile = beanForm.getAttachFile();
		if(attachFile != null && StringUtils.isNotBlank(attachFile.getFileName())){
			HreJobInterviewAttachment attach = baseService.getFirstPojo("interviewId", Compare.EQUAL, tmp.getId(), null, null, 0, HreJobInterviewAttachment.class);
			if(attach == null){
				attach = new HreJobInterviewAttachment();
			}
			attach.setFileType(attachFile.getContentType());
			attach.setInterviewId(tmp.getId());
			attach.setFileSize(attachFile.getFileSize());
			attach.setDateModified(new Date());
			attach.setDateCreated(new Date());
			attach.setFileName(attachFile.getFileName());
			attach.setFileContent(attachFile.getFileData());

			baseService.saveOrUpdate(attach);
		}

		response.getWriter().write(
				 "<script language=\"javascript\">\n" +
						" parent.dw.close();" + 
						 " var param = parent.document.createElement('input'); " +
						 " param.type = 'hidden'; " +
						 " param.name = 'vacId'; " +
						 " param.value = " + tmp.getVacancyId() +  ";" +
						 " parent.document.forms[0].appendChild(param);" +
						" parent.document.forms[0].submit(); \n" +
				 "</script>");
		return null;
	}

	public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		CommonUtils.println(CommonUtils.getSourceCodeLocation());
		InterviewUpdateForm beanForm = (InterviewUpdateForm) form;
		beanForm.setIsAddNew(false);
		
		if(request.getParameter(StringConstants.BTN_EDIT) == null){
			
			int id = CommonUtils.getIntParameter("id", request);
			HreJobInterview tmp = baseService.getFirstPojo("id", Compare.EQUAL, id, null, null, 0, HreJobInterview.class);
			
			if (tmp == null) {
				beanForm.setMessage(StringConstants.BLANK);
				initFormBean(beanForm);
				return mapping.findForward(ACTION_NAME);
			}

			beanForm.setId(id);
			beanForm.setCanId(tmp.getCandidateId());
			beanForm.setVacId(tmp.getVacancyId());
			beanForm.setName(CommonUtils.normalizeString(tmp.getInterviewName()));
			beanForm.setPlace(CommonUtils.normalizeString(tmp.getInterviewPlace()));
			beanForm.setStatus(tmp.getStatus());
			beanForm.setResult(tmp.getResult());
			beanForm.setDate(CommonUtils.dateToString(tmp.getInterviewTime()));
			beanForm.setInterviewer1(CommonUtils.getEmpNameAndUsername(tmp.getInterviewer1()));
			beanForm.setInterviewer2(CommonUtils.getEmpNameAndUsername(tmp.getInterviewer2()));
			beanForm.setInterviewer3(CommonUtils.getEmpNameAndUsername(tmp.getInterviewer3()));
			beanForm.setInterviewer4(CommonUtils.getEmpNameAndUsername(tmp.getInterviewer4()));
			beanForm.setInterviewer5(CommonUtils.getEmpNameAndUsername(tmp.getInterviewer5()));
			
			int hour = 0;
			int min = 0;
			if (tmp.getInterviewTime() != null) {
				hour = tmp.getInterviewTime().getHours();
				min = tmp.getInterviewTime().getMinutes();
			}
			beanForm.setHour(hour + "");
			beanForm.setMin(min + "");

			beanForm.setMessage(StringConstants.BLANK);
			initFormBean(beanForm);
			return mapping.findForward(ACTION_NAME);
		}

		String message = validateForm(beanForm);
		if(!StringUtils.isBlank(message)){
			beanForm.setMessage(message);
			initFormBean(beanForm);
			return mapping.findForward(ACTION_NAME);
		}

		HreJobInterview tmp = baseService.getFirstPojo("id", Compare.EQUAL, beanForm.getId(), null, null, 0, HreJobInterview.class);		
		if (tmp == null) {
			beanForm.setMessage(StringConstants.BLANK);
			initFormBean(beanForm);
			return mapping.findForward(ACTION_NAME);
		}

		tmp.setCandidateId(beanForm.getCanId());
		tmp.setVacancyId(beanForm.getVacId());
		tmp.setInterviewName(getInterviewName(tmp));
		tmp.setInterviewPlace(CommonUtils.normalizeString(beanForm.getPlace()));
		tmp.setStatus(beanForm.getStatus());
		tmp.setResult(beanForm.getResult());
		getAllInterviewers(beanForm, tmp);

		Date date = CommonUtils.stringToDate(CommonUtils.normalizeString(beanForm.getDate()));
		if (date != null) {
			try {
				int hour = Integer.parseInt(beanForm.getHour());
				int min = Integer.parseInt(beanForm.getMin());
				date.setHours(hour);
				date.setMinutes(min);
			} catch (Exception e) {

			}
		}
		tmp.setInterviewTime(date);
		tmp.setDateModified(new Date());

		boolean status = baseService.saveOrUpdate(tmp);
		if (!status) {
			beanForm.setMessage(StringConstants.UPDATE_FAILURE_MESSAGE);
			initFormBean(beanForm);
			return mapping.findForward(ACTION_NAME);
		}
		
		getRecipientInfo(tmp);
		
		// Inform interviewers & interviewee about interview changes.
		informIntervieweeToInterviewChange(tmp);
		informInterviewerForInterviewChange(tmp);
		
		// Inform the INTERVIEWEE for interview result.
		if (tmp.getResult() == 2) { // Passed.
			informIntervieweeForInterviewSuccess(tmp);
		} else if (tmp.getResult() == 3) { // Failed.
			informIntervieweeForInterviewFailure(tmp);
		}

		FormFile attachFile = beanForm.getAttachFile();
		if(attachFile != null && StringUtils.isNotBlank(attachFile.getFileName())){
			HreJobInterviewAttachment attach = baseService.getFirstPojo("interviewId", Compare.EQUAL, tmp.getId(), null, null, 0, HreJobInterviewAttachment.class);
			if(attach == null){
				attach = new HreJobInterviewAttachment();
			}
			attach.setFileType(attachFile.getContentType());
			attach.setInterviewId(tmp.getId());
			attach.setFileSize(attachFile.getFileSize());
			attach.setDateModified(new Date());
			attach.setDateCreated(new Date());
			attach.setFileName(attachFile.getFileName());
			attach.setFileContent(attachFile.getFileData());

			baseService.saveOrUpdate(attach);
		}

		response.getWriter().write(
				 "<script language=\"javascript\">\n" +
						" parent.dw.close();" + 
						 " var param = parent.document.createElement('input'); " +
						 " param.type = 'hidden'; " +
						 " param.name = 'vacId'; " +
						 " param.value = " + tmp.getVacancyId() +  ";" +
						 " parent.document.forms[0].appendChild(param);" +
						" parent.document.forms[0].submit(); \n" +
				 "</script>");
		return null;
	}

	private void initFormBean (InterviewUpdateForm beanForm) {

		beanForm.setAllStatuses(ComboBoxInit.getAllInterviewStatuses(false));
		beanForm.setAllResults(ComboBoxInit.getAllInterviewResults(false));
		beanForm.setAllInterviewers(ComboBoxInit.getAllEmployees(true));
		beanForm.setAllCandidates(ComboBoxInit.getAllCandidates(false));
		beanForm.setAllVacancies(ComboBoxInit.getAllVacancies(false));
	}
	
	private String validateForm (InterviewUpdateForm beanForm) {		

		int hour = 0;
		int min = 0;
		Calendar cal = CommonUtils.stringToCalendar(beanForm.getDate());
		
		if (cal != null) {
			try {
	
				hour = Integer.parseInt(beanForm.getHour());
				if (hour < 0 || hour > 23) {
					return "Hour must be an integer in the range from 0 to 23.";
				}
			} catch (Exception e) {
				return "Hour must be an integer in the range from 0 to 23.";
			}
			
			try {
	
				min = Integer.parseInt(beanForm.getMin());
				if (min < 0 || min > 59) {
					return "Minute must be an integer in the range from 0 to 59.";
				}
			} catch (Exception e) {
				return "Minute must be an integer in the range from 0 to 59.";
			}
		}
		
		FormFile attachFile = beanForm.getAttachFile();
		if(attachFile != null && StringUtils.isNotBlank(attachFile.getFileName())){
			if(attachFile.getFileSize() > 2097152){
				return "Attached file size is too large! (< 2 MB required!)";
			} else if(!"application/pdf".equalsIgnoreCase(attachFile.getContentType())
					&& !"application/msword".equalsIgnoreCase(attachFile.getContentType())
					&& !"application/vnd.openxmlformats-officedocument.wordprocessingml.document".equalsIgnoreCase(attachFile.getContentType())){
				return "Attached file type is not valid! (Only .pdf, .doc or .docx files are accepted!)";
			}
		}

		return StringConstants.BLANK;
	}
	
	private void getAllInterviewers (InterviewUpdateForm beanForm, HreJobInterview tmp) {

		ArrayList<String> params = new ArrayList<String>();
		params.add(beanForm.getInterviewer1());
		params.add(beanForm.getInterviewer2());
		params.add(beanForm.getInterviewer3());
		params.add(beanForm.getInterviewer4());
		params.add(beanForm.getInterviewer5());
		
		String sql = "SELECT emp.emp_number AS col1" +
				" FROM hre_employee AS emp" +
				" WHERE CONCAT(emp.emp_lastname, ' ', emp.emp_middle_name, ' ', emp.emp_firstname, ' [', emp.main_username, ']') IN (?, ?, ?, ?, ?) ";
		
		List <Object[]> listObject = baseService.listArrayObject(sql, -1, 0, params.toArray());
		if (listObject == null || listObject.size() < 1) {
			tmp.setInterviewer1(null);
			tmp.setInterviewer2(null);
			tmp.setInterviewer3(null);
			tmp.setInterviewer4(null);
			tmp.setInterviewer5(null);
			return;
		}

		int interviewer1 = 0;
		int interviewer2 = 0;
		int interviewer3 = 0;
		int interviewer4 = 0;
		int interviewer5 = 0;
		int size = listObject.size(); 
		switch (size) {
			case 5:
				Object[] objs = listObject.get(4);
				interviewer5 = CommonUtils.parseInt(objs[1] == null ? "-1" : objs[1].toString(), -1);
			case 4:
				objs = listObject.get(3);
				interviewer4 = CommonUtils.parseInt(objs[1] == null ? "-1" : objs[1].toString(), -1); 
			case 3:
				objs = listObject.get(2);
				interviewer3 = CommonUtils.parseInt(objs[1] == null ? "-1" : objs[1].toString(), -1);
			case 2:
				objs = listObject.get(1);
				interviewer2 = CommonUtils.parseInt(objs[1] == null ? "-1" : objs[1].toString(), -1);
			case 1:
				objs = listObject.get(0);
				interviewer1 = CommonUtils.parseInt(objs[1] == null ? "-1" : objs[1].toString(), -1);
				break;
			default:
				tmp.setInterviewer1(null);
				tmp.setInterviewer2(null);
				tmp.setInterviewer3(null);
				tmp.setInterviewer4(null);
				tmp.setInterviewer5(null);
				return;
		}
		
		if (interviewer1 > 0) {
			tmp.setInterviewer1(interviewer1);
		} else {
			tmp.setInterviewer1(null);
		}
		
		if (interviewer2 > 0) {
			tmp.setInterviewer2(interviewer2);
		} else {
			tmp.setInterviewer2(null);
		}
		
		if (interviewer3 > 0) {
			tmp.setInterviewer3(interviewer3);
		} else {
			tmp.setInterviewer3(null);
		}
		
		if (interviewer4 > 0) {
			tmp.setInterviewer4(interviewer4);
		} else {
			tmp.setInterviewer4(null);
		}
		
		if (interviewer5 > 0) {
			tmp.setInterviewer5(interviewer5);
		} else {
			tmp.setInterviewer5(null);
		}
	}

	private String getInterviewName (HreJobInterview tmp) {

		HreJobCandidate tmpCan = baseService.getFirstPojo("id", Compare.EQUAL, tmp.getCandidateId(), HreJobCandidate.class);
		HreJobVacancy tmpVac = baseService.getFirstPojo("id", Compare.EQUAL, tmp.getVacancyId(), HreJobVacancy.class);
		String interviewName = "Interview";
		if (tmpCan != null) {
			interviewName += " " + tmpCan.getLastName();
			if (!"".equals(tmpCan.getMiddleName())) {
				interviewName += " " + tmpCan.getMiddleName();
			}
			interviewName += " " + tmpCan.getFirstName();
		}
		if (tmpVac != null) {
			interviewName += " for " + tmpVac.getName();
		}
		
		return interviewName;
	}
	
	private void getRecipientInfo (HreJobInterview tmp) {
		
		HreJobCandidate tmpCan = baseService.getFirstPojo("id", Compare.EQUAL, tmp.getCandidateId(), HreJobCandidate.class);
		if (tmpCan != null && !"".equals(tmpCan.getEmail())) {
			canName = tmpCan.getFirstName();
			if (tmpCan.getMiddleName() != null && !"".equals(tmpCan.getMiddleName())) {
				canName += tmpCan.getMiddleName();
			}
			canEmail = tmpCan.getEmail();
		}
		
		HreJobVacancy tmpVac = baseService.getFirstPojo("id", Compare.EQUAL, tmp.getVacancyId(), HreJobVacancy.class);
		if (tmpVac != null) {
			vacName = tmpVac.getName(); 
		}

		String sql = "";
		ArrayList<Object> params = new ArrayList<Object>();
		params.add(tmp.getInterviewer1());
		params.add(tmp.getInterviewer2());
		params.add(tmp.getInterviewer3());
		params.add(tmp.getInterviewer4());
		params.add(tmp.getInterviewer5());

		sql = "SELECT emp.emp_work_email AS col1" +

					" FROM hre_employee AS emp" +

					" WHERE emp.is_deleted = 0 " +
					" AND emp.emp_number IN (?, ?, ?, ?, ?)";
		
		Vector<String> listRecipients = new Vector<String>();

		List <Object[]> listObject = baseService.listArrayObject(sql, -1, 0, params.toArray());
		for(int i = 0; listObject != null && i < listObject.size(); i++){
			
			try {

				Object[] objs = listObject.get(i);
				listRecipients.add(CommonUtils.normalizeObjectToString(objs[1], ""));
			} catch (Exception e) {
				CommonUtils.println(e.getMessage());
			}
		}
		
		String[] lstStrings = new String[listRecipients.size()];
		for (int ind = 0; ind < listRecipients.size(); ind++) {
			lstStrings[ind] = listRecipients.get(ind);
		}
		
		interviewerEmailList = lstStrings;
	}
	
	private void informIntervieweeToInterview (HreJobInterview tmp) {
		
		if (tmp == null) {
			return;
		}

		String message = "Dear " + canName + "!\n\n";
		message += "The human resource department of Telsoft Joint Stock company kindly informs you that an interview has been setup for you" +
				" in the progress of applying to the position " + vacName + ".";
		
		if (tmp != null && tmp.getInterviewTime() != null) {
			message += " The interview is on " + CommonUtils.dateToString(tmp.getInterviewTime()) + ", at " + tmp.getInterviewTime().getHours() + "h" + tmp.getInterviewTime().getMinutes() + ".";
		}
		if (tmp != null && !"".equals(tmp.getInterviewPlace())) {
			message += " The interview will take place at " + tmp.getInterviewPlace() + ".";
		}
		message += "\n\nPlease prepare for the interview carefully and be on time!";
		
		message += "\n\nThanks and best regards!";
		message += "\nHuman Resource Department - Telsoft JSC.";
		
		emailSender.sendMail(new String[]{canEmail}, "Interview Schedule - Human Resource Department - Telsoft JSC.", message, false);
	}
	
	private void informIntervieweeForInterviewSuccess (HreJobInterview tmp) {
		
		if (tmp == null) {
			return;
		}

		String message = "Congratulations " + canName + "!\n\n";
		message += "The human resource department of Telsoft Joint Stock company kindly informs you that you have passed the interview" +
				" in the progress of applying to the position " + vacName + ".";
		message += " We will sent to you the offer later as soon as posible for more information about this employment.";
		
		message += "\n\nThanks and best regards!";
		message += "\nHuman Resource Department - Telsoft JSC.";
		
		emailSender.sendMail(new String[]{canEmail}, "Interview Result - Human Resource Department - Telsoft JSC.", message, false);
	}
	
	private void informIntervieweeForInterviewFailure (HreJobInterview tmp) {
		
		if (tmp == null) {
			return;
		}

		String message = "Dear " + canName + "!\n\n";
		message += "We are really sorry to inform you that you have failed to" +
				" apply to the position " + vacName + ".";
		message += " This failure does not mean that you are not able to do what the job requires, it simply means you skills are not appropriate for the positions.";
		message += " Thank you a lot for your consideration and have a better luck next time.";
		
		message += "\n\nBest regards!";
		message += "\nHuman Resource Department - Telsoft JSC.";
		
		emailSender.sendMail(new String[]{canEmail}, "Interview Result - Human Resource Department - Telsoft JSC.", message, false);
	}
	
	private void informInterviewerForInterview (HreJobInterview tmp) {
		
		if (tmp == null) {
			return;
		}

		String message = "Dear sir (madam)!\n\n";
		
		message += "Human Resource Department kindly informs you that you were invited to be the interviewers of \"" + getInterviewName(tmp) + "\".";
		if (tmp != null && tmp.getInterviewTime() != null) {
			message += " The interview is on " + CommonUtils.dateToString(tmp.getInterviewTime()) + ", at " + tmp.getInterviewTime().getHours() + "h" + tmp.getInterviewTime().getMinutes() + ".";
		}
		if (tmp != null && !"".equals(tmp.getInterviewPlace())) {
			message += " The interview will take place at " + tmp.getInterviewPlace() + ".";
		}
		message += "\n\nPlease prepare for the interview carefully and be on time!";
		message += "\n\nBest regards!";
		message += "\nHuman Resource Department - Telsoft JSC.";
		
		emailSender.sendMail(interviewerEmailList, "Interview Schedule - Human Resource Department - Telsoft JSC.", message, false);
	}
	
	private void informInterviewerForInterviewChange (HreJobInterview tmp) {
		
		if (tmp == null) {
			return;
		}

		String message = "Dear sir (madam)!\n\n";
		
		message += "Human Resource Department kindly informs you that some information of the interview \"" + getInterviewName(tmp) + "\" has been changed.";
		if (tmp != null && tmp.getInterviewTime() != null) {
			message += " The interview is now on " + CommonUtils.dateToString(tmp.getInterviewTime()) + ", at " + tmp.getInterviewTime().getHours() + "h" + tmp.getInterviewTime().getMinutes() + ".";
		}
		if (tmp != null && !"".equals(tmp.getInterviewPlace())) {
			message += " The interview will take place at " + tmp.getInterviewPlace() + ".";
		}
		message += "\n\nPlease prepare for the interview carefully and be on time!";
		
		message += "\n\nBest regards!";
		message += "\nHuman Resource Department - Telsoft JSC.";
	
		emailSender.sendMail(interviewerEmailList, "Interview Schedule Changed - Human Resource Department - Telsoft JSC.", message, false);
	}
	
	private void informIntervieweeToInterviewChange (HreJobInterview tmp) {
		
		if (tmp == null) {
			return;
		}

		String message = "Dear " + canName + "!\n\n";
		message += "The human resource department of Telsoft Joint Stock company kindly informs you that the interview has been setup for you" +
				" in the progress of applying to the position " + vacName + " has been changed for some information.";
		if (tmp != null && tmp.getInterviewTime() != null) {
			message += " The interview is now on " + CommonUtils.dateToString(tmp.getInterviewTime()) + ", at " + tmp.getInterviewTime().getHours() + "h" + tmp.getInterviewTime().getMinutes() + ".";
		}
		if (tmp != null && !"".equals(tmp.getInterviewPlace())) {
			message += " The interview will take place at " + tmp.getInterviewPlace() + ".";
		}
		message += "\n\nPlease prepare for the interview carefully and be on time!";
		
		message += "\n\nThanks and best regards!";
		message += "\nHuman Resource Department - Telsoft JSC.";
		
		emailSender.sendMail(new String[]{canEmail}, "Interview Schedule Changed - Human Resource Department - Telsoft JSC.", message, false);
	}
}
